package com.example.springinaction.scope;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Service;
import org.springframework.web.context.WebApplicationContext;

@Service
public class StoreService {

    private ShoppingCart shoppingCart;

    @Autowired
    public void setShoppingCart(ShoppingCart shoppingCart){
        this.shoppingCart = shoppingCart;
    }

    /**
     * proxyMode = ScopedProxyMode.INTERFACES 解决了将会话或请求作用域的bean注入到单例bean中所遇到的问题
     * proxyMode = ScopedProxyMode.INTERFACES 表明这个代理要实现ShoppingCart接口,并将调用委托给实现Bean.
     * @return
     */
    @Bean
    @Scope(value = WebApplicationContext.SCOPE_SESSION,proxyMode = ScopedProxyMode.INTERFACES)
    public ShoppingCart shoppingCart(){
        return new Cart();
    }
}
/**
 * 1. StoreService是一个单例的bean,会在Spring上下文加载的时候创建.当它创建的时候,Spring会试图将ShoppingCart bean 注入到 setShoppingCart方法中
 * 但是ShoppingCart是 session 作用域,此时并不存在.直到某个用户进入系统创建了会话才会出现shoppingcart实例.
 * 2. 系统中会存在多个ShoppingCart实例,每个用户一个.我们并不想让Spring注入某个固定的ShoppingCart实例到StoreService中.我们希望的是当StoreService
 * 处理购物车时,它所使用的ShoppingCart恰好是当前会话对应的那个.\
 *
 * Spring并不会将实际的ShoppingCart bean注入到 StoreService中,Spring会注入一个到ShoppingCart bean的代理(beanWrapper).当StoreService真正调用
 * Shoppingcart的方法时,代理会对其进行懒解析并将调用委托给 session 作用域内真正的ShoppingCart bean.
 *
 */
